package anonymouschat.client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import anonymouschat.client.frames.ChatFrame;
import anonymouschat.messages.TextMessage;
import anonymouschat.messages.serverresponses.ChatroomChangeResponse;
import anonymouschat.messages.serverresponses.ChatroomMemberResponse;


/**
 * This thread receives incoming
 * 
 * 1. text messages
 * 
 * 2. chat member response
 * 
 * 
 * @author bh349
 * 
 */
public class ClientInConnectionThread extends Thread {
	private ChatFrame chatFrame;

	private Socket incomingSocket;
	ObjectInputStream in = null;
	ObjectOutputStream out = null; //needed to write the initial AnnoinceMessage to server

	public ClientInConnectionThread(ChatFrame chatFrame, Socket clientSocket) {
		this.chatFrame = chatFrame;
		this.incomingSocket = clientSocket;
	}
	
	/**
	 * Wait for out to be created and then return it. This method exists 
	 * because we can't use a socket's output stream to create a 
	 * object output stream more than once
	 * TODO May need to have a time out and exception throw 
	 * @return
	 */
	public ObjectOutputStream getOutputStream(){
	    while(this.out == null){
	        try {
                Thread.sleep( 20);
            } catch( InterruptedException e ) {
                e.printStackTrace();
            }
	    }
	    return out;
	}
	
	public void run() {
	    
	    // create output stream
	    try {
	        out = new ObjectOutputStream(incomingSocket.getOutputStream());
	    } catch( IOException e1 ) {
	        e1.printStackTrace();
	    }

	    Object receivedMessage = null;
	    boolean openSocket = true;
	    try {
	        in = new ObjectInputStream(incomingSocket.getInputStream());
	    } catch( IOException e1 ) {
	        e1.printStackTrace();
	    }
	    while (openSocket  == true){
	        try {	    
	            try {
	                receivedMessage = in.readObject();
	                if (receivedMessage instanceof TextMessage) {
	                    chatFrame.showTextMessage((TextMessage) receivedMessage);
	                } else if (receivedMessage instanceof ChatroomMemberResponse) {
	                	  chatFrame.updateChatMemberPanel((ChatroomMemberResponse)receivedMessage);
	                }else if(receivedMessage instanceof ChatroomChangeResponse){
	                    ChatroomChangeResponse resp = (ChatroomChangeResponse)receivedMessage;
	                    if(resp.isSuccess()){
	                        chatFrame.switchChatroomOk(resp.getDstChatroomName());
	                    }else{
	                        chatFrame.showError( "Chat room is full. Cannot join." );
	                    }
	                }

	            } catch (ClassNotFoundException e) {
	                e.printStackTrace();
	            }

	        } catch (IOException ioe) {
	            ioe.printStackTrace();
	            openSocket = false; //Socket Closed, die gracefully
	        }

	    }//END-WHILE
	    try {
	        if (in != null) in.close();
	        if (incomingSocket != null) incomingSocket.close();
	    } catch( IOException e ) {
	        e.printStackTrace();
	    }
	}
}
